﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.AccessControl;

namespace CopyGACAssembly
{
    class Program
    {
        private static string[] GAC = { "GAC", "GAC_32", "GAC_64", "GAC_MSIL" };

        static void Main(string[] args)
        {
            string userPath = "";
            if (args.Length == 0)
            {
                userPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
                System.IO.FileInfo info = new System.IO.FileInfo(userPath);
                userPath = info.DirectoryName;
            }
            else
            {
                userPath = System.IO.Path.GetFullPath(args[0]);
                if (!System.IO.Directory.Exists(userPath))
                {
                    try
                    {
                        System.IO.Directory.CreateDirectory(userPath);
                    }
                    catch (System.UnauthorizedAccessException)
                    {
                        Console.WriteLine("Please run as administrator.");
                        return;
                    }
                    catch (System.Exception e)
                    {
                        Console.WriteLine(e.Message);
                        return;
                    }
                }
            }

            //check permission
            bool canCreateFile = false;
            AuthorizationRuleCollection col = 
                System.IO.Directory.GetAccessControl(userPath).GetAccessRules(true, true, 
                Type.GetType("System.Security.Principal.SecurityIdentifier"));
            foreach (FileSystemAccessRule rul in col)
                if (rul.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) 
                { 
                    canCreateFile = true; break; 
                }
            if (!canCreateFile)
            {
                Console.WriteLine("Don't have rights to create file in " + userPath);
                return;
            }

            Console.WriteLine("Copy to " + userPath);
            userPath += @"\";

            foreach (string g in GAC)
            {
                string path = @"C:\Windows\assembly\" + g;
                if (!System.IO.Directory.Exists(path)) continue;

                System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(path);                           
                System.IO.FileInfo[] files = info.GetFiles("ESRI.ArcGIS.*.dll", System.IO.SearchOption.AllDirectories);
                if (files.Length == 0) continue;

                string destinationPath = userPath + g;
                if (!System.IO.Directory.Exists(destinationPath))
                    System.IO.Directory.CreateDirectory(destinationPath);

                foreach (System.IO.FileInfo f in files)
                {
                    System.IO.File.Copy(f.FullName,
                        destinationPath + @"\" + f.Name,true);
                    Console.WriteLine("Copying " + f.Name);
                }
            }
            Console.WriteLine("finished");
            Console.ReadLine();
        }
    }
}
